package com.example.book_subscribe.common.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class RedisTokenService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String TOKEN_PREFIX = "token:";

    /**
     * 存储 token 并设置过期时间
     *
     * @param token    要存储的 token
     * @param timeout  过期时间（秒）
     */
    public void saveToken(String token, long timeout) {
        redisTemplate.opsForValue().set(TOKEN_PREFIX + token, token, timeout, TimeUnit.SECONDS);
    }

    /**
     * 根据 token 获取存储的 token 信息
     *
     * @param token 要获取的 token
     * @return 返回 token，如果不存在则返回 null
     */
    public String getToken(String token) {
        return redisTemplate.opsForValue().get(TOKEN_PREFIX + token);
    }

    /**
     * 判断 token 是否过期
     *
     * @param token 要判断的 token
     * @return true 表示 token 未过期，false 表示 token 已过期或不存在
     */
    public boolean isTokenExpired(String token) {
        Long expire = redisTemplate.getExpire(TOKEN_PREFIX + token, TimeUnit.SECONDS);
        return expire != null && expire > 0;
    }

    /**
     * 根据 token 重新设置其过期时间
     *
     * @param token   需要重新设置过期时间的 token
     * @param timeout 新的过期时间（秒）
     * @return true 表示重设成功，false 表示 token 不存在或已过期
     */
    public boolean resetTokenExpiration(String token, long timeout) {
        String storedToken = redisTemplate.opsForValue().get(TOKEN_PREFIX + token);
        if (storedToken != null) {
            redisTemplate.expire(TOKEN_PREFIX + token, timeout, TimeUnit.SECONDS);
            return true;
        }
        return false;

    }

    /**
     * 根据 token 删除存储的 token
     *
     * @param token 要删除的 token
     * @return true 表示删除成功，false 表示 token 不存在或删除失败
     */
    public boolean deleteToken(String token) {
        Boolean result = redisTemplate.delete(TOKEN_PREFIX + token);
        return result != null && result;
    }

}
